%{

#include <stdio.h>
#include <math.h>
extern int yylex(void);
extern char *yytext;
extern int yylineno;
void yyerror (char *s);
%}

%union
{
   float real;
   int entero;
   char caracter;
   char* string; 
}
%error-verbose
%start CreateInicio

/*INICIALES*/
%token <string> TKN_CREATE
%token <string> TKN_DROP
%token <string> TKN_ALTER
%token <string> TKN_TRUNCATE

/*TIPOS DE VARIABLE*/
%token <string> TKN_CHARACTER
%token <string> TKN_VARCHAR
%token <string> TKN_NUMERIC
%token <string> TKN_DECIMAL
%token <string> TKN_INTEGER
%token <string> TKN_SMALLINT
%token <string> TKN_FLOAT
%token <string> TKN_REAL
%token <string> TKN_DOUBLEPRECISION
%token <string> TKN_LONGVARCHAR
%token <string> TKN_LONGVARBINARY
%token <string> TKN_TIMESTAMP
%token <string> TKN_DATETIME
%token <string> TKN_TIME
%token <string> TKN_DATE
%token <string> TKN_OWNER	
%token <string> TKN_BIT
%token <string> TKN_VARBIT
%token <string> TKN_CLOB
%token <string> TKN_BLOB
%token <string> TKN_BOOL	
   
	    
/*CONSTRAINTS*/
%token <string> TKN_CHECK 
%token <string> TKN_UNIQUE
%token <string> TKN_NOTNULL
%token <string> TKN_PRIMARYKEY
%token <string> TKN_FOREIGNKEY
%token <string> TKN_DEFAULT
%token <string> TKN_IDENTITY
%token <string> TKN_REFERENCES
%token <string> TKN_CONSTRAINT
%token <string> TKN_NOACTION
%token <string> TKN_SETDEFAULT
%token <string> TKN_CASCADE
%token <string> TKN_SETNULL 
%token <string> TKN_ONDELETE
%token <string> TKN_ONUPDATE

/*COMPARACION*/
%token TKN_MENORQUE
%token TKN_MAYORQUE
%token TKN_IGUALDAD
%token <string> TKN_MAYOROIGUAL
%token <string> TKN_MENOROIGUAL
%token <string> TKN_DIFERENTE

/*EXTRA*/
%token <string> TKN_AND
%token <string> TKN_OR
%token <string> TKN_XOR
%token <string> TKN_NOT
%token <string> TKN_ON
%token <string> TKN_AS
%token <string> TKN_COLUMN
%token <string> TKN_ADD

%token <real> TKN_NUM
%token <entero> TKN_INTNUM
%token <caracter> TKN_CHAR
%token TKN_IGUAL
%token TKN_COMA
%token TKN_PTOCOMA
%token TKN_COMILLAS
%token TKN_MULT
%token TKN_DIV
%token TKN_MAS
%token TKN_MENOS
%token TKN_LP
%token TKN_RP
%token TKN_CREATEALGO
%token <string> TKN_TIPO
%token <char> TKN_ADICIONAL
%token <real> TKN_ID
%token <string> TKN_TABLE
%token <string> TKN_INDEX
%token <string> TKN_DATABASE
%token <string> TKN_VIEW
%token <string> TKN_PROCEDURE
%token <string> TKN_TRIGGER
%token <string> TKN_NOMBRE

//%type <int> var_numerica
//%type <char> var_char
//%type <string> op_adicional

%left TKN_MAS TKN_MENOS
%left TKN_MULT TKN_DIV

%%
CreateInicio 
		: Accion
Accion
		:TKN_CREATE SigueCreate Denuevo
		|TKN_DROP SigueDrop
		|TKN_ALTER SigueAlter
		|TKN_TRUNCATE TKN_TABLE TKN_NOMBRE
		|error TKN_PTOCOMA Denuevo {yyerrok;}
;
SigueCreate
		:TKN_TABLE TKN_NOMBRE TKN_LP Desicion TKN_RP TKN_PTOCOMA
		|TKN_TABLE TKN_NOMBRE error Desicion TKN_RP TKN_PTOCOMA {yyerrok;}
		|TKN_TABLE TKN_NOMBRE error TKN_COMA Desicion TKN_RP TKN_PTOCOMA {yyerrok;}
		|TKN_TABLE TKN_NOMBRE TKN_LP Desicion error TKN_PTOCOMA {yyerrok;}
		|TKN_UNIQUE TKN_INDEX TKN_NOMBRE TKN_ON TKN_NOMBRE TKN_LP uno_o_varios TKN_RP
		|TKN_INDEX TKN_NOMBRE TKN_ON TKN_NOMBRE TKN_LP uno_o_varios TKN_RP
		|error TKN_NOMBRE TKN_LP Desicion TKN_RP TKN_PTOCOMA
 {yyerrok;}
;
Denuevo	:{printf("\nFIN!\n");}
		|Accion
		;
SigueDrop
		:TKN_TABLE TKN_NOMBRE
		|TKN_INDEX TKN_NOMBRE
		|TKN_DATABASE TKN_NOMBRE
;
SigueAlter
		:TKN_TABLE TKN_NOMBRE Alteracion
		|TKN_INDEX TKN_NOMBRE
		|TKN_DATABASE TKN_NOMBRE
;
Alteracion
		:TKN_ADD TKN_NOMBRE data_type
		|TKN_DROP TKN_COLUMN TKN_NOMBRE 
		|TKN_ALTER TKN_COLUMN TKN_NOMBRE data_type
;
uno_o_varios
		:TKN_NOMBRE uno_o_varios2
		;
uno_o_varios2
		:
		|TKN_COMA uno_o_varios
;
Desicion : 
		
		|TKN_NOMBRE data_type op_adicional Desicion2
		|TKN_PRIMARYKEY TKN_LP uno_o_varios TKN_RP Desicion2
		|TKN_FOREIGNKEY TKN_LP uno_o_varios TKN_RP TKN_REFERENCES TKN_NOMBRE TKN_LP uno_o_varios TKN_RP foreign_accion Desicion2
		|TKN_CONSTRAINT TKN_NOMBRE TKN_UNIQUE TKN_LP uno_o_varios TKN_RP Desicion2
		|TKN_CONSTRAINT TKN_NOMBRE TKN_PRIMARYKEY TKN_LP uno_o_varios TKN_RP Desicion2
		|TKN_CONSTRAINT TKN_NOMBRE TKN_FOREIGNKEY TKN_LP uno_o_varios TKN_RP TKN_REFERENCES TKN_NOMBRE TKN_LP uno_o_varios TKN_RP foreign_accion Desicion2
;
Desicion2 
		: 
		|TKN_COMA Desicion
		|TKN_PTOCOMA 
;
data_type
	    : TKN_CHARACTER 
	    | TKN_VARCHAR 
	    | TKN_VARCHAR TKN_LP TKN_INTNUM TKN_RP
	    | TKN_CHARACTER TKN_LP TKN_INTNUM TKN_RP
	    | TKN_NUMERIC
	    | TKN_NUMERIC TKN_LP TKN_INTNUM TKN_RP
| TKN_NUMERIC TKN_LP TKN_INTNUM TKN_COMA TKN_INTNUM TKN_RP
	    | TKN_DECIMAL
	    | TKN_DECIMAL TKN_LP TKN_INTNUM TKN_RP
| TKN_DECIMAL TKN_LP TKN_INTNUM TKN_COMA TKN_INTNUM TKN_RP
	    | TKN_INTEGER
	    | TKN_SMALLINT
	    | TKN_FLOAT
	    | TKN_FLOAT TKN_LP TKN_INTNUM TKN_RP
	    | TKN_REAL
	    | TKN_DOUBLEPRECISION
	    | TKN_LONGVARCHAR
	    | TKN_LONGVARBINARY
	    | TKN_TIMESTAMP
	    | TKN_DATETIME
	    | TKN_TIME 
	    | TKN_DATE 
	    | TKN_OWNER
		|TKN_BIT TKN_LP TKN_INTNUM TKN_RP
		|TKN_VARBIT TKN_LP TKN_INTNUM TKN_RP
|TKN_CLOB
|TKN_BLOB
|TKN_BOOL
	    ;
op_adicional
		:
		|TKN_CHECK TKN_LP expresion TKN_RP op_adicional
		|TKN_UNIQUE op_adicional
		|TKN_NOTNULL op_adicional
		|TKN_PRIMARYKEY op_adicional
		|TKN_DEFAULT TKN_COMILLAS TKN_NOMBRE TKN_COMILLAS op_adicional
		|TKN_DEFAULT TKN_INTNUM op_adicional
		|TKN_IDENTITY TKN_LP TKN_INTNUM TKN_COMA TKN_INTNUM TKN_RP op_adicional
		|TKN_IDENTITY TKN_LP TKN_INTNUM TKN_COMA TKN_INTNUM TKN_RP  op_adicional
		|TKN_REFERENCES TKN_NOMBRE TKN_LP TKN_NOMBRE TKN_RP foreign_accion op_adicional 
		;

foreign_accion
			:
			|TKN_ONDELETE foreign_mod
			|TKN_ONUPDATE foreign_mod
foreign_mod
			:
			|TKN_NOACTION
			|TKN_SETDEFAULT
			|TKN_CASCADE
			|TKN_SETNULL
			
			
expresion
		: 
		TKN_NOMBRE compara TKN_INTNUM expresion2
		|TKN_NOMBRE error TKN_INTNUM expresion2{yyerrok;}
		|TKN_NOMBRE compara TKN_COMILLAS TKN_NOMBRE TKN_COMILLAS expresion2 expresion
		|TKN_NOMBRE error TKN_COMILLAS TKN_NOMBRE TKN_COMILLAS expresion2 expresion {yyerrok;}
		;
expresion2
		:
		|TKN_AND 
		|TKN_OR 
		|TKN_XOR 
		|TKN_NOT 
		;
compara
		:
TKN_IGUALDAD
|TKN_MAYORQUE
|TKN_MENORQUE
|TKN_DIFERENTE
|TKN_MENOROIGUAL
|TKN_MAYOROIGUAL
		;
%%

void yyerror(char *s)
{
   printf("Error: %s INSTEAD OF(%s) LINE(%d) \n", s,yytext,yylineno);

}

int main()
{
   extern FILE*  yyin;
   yyin = fopen("filename", "r");
   yyparse();
   return 0;
}